﻿using System;
using System.Linq;
using System.Xml.Linq;
using TestsModel.Data;
using TestsModel.Enums;

namespace TestsModel.Parsers
{
    public class XmlTestParser
    {
        public static TestData ParseXmlFile(XDocument xDocument)
        {
            var testData = new TestData();

            if (xDocument != null && xDocument.Root != null)
            {
                foreach (var questionElement in xDocument.Root.Elements("Question"))
                {
                    TestTypes testType;
                    if (Enum.TryParse(questionElement.Attribute("type").Value, true, out testType))
                    {
                        switch (testType)
                        {
                            case TestTypes.CheckTest:
                                testData.CheckTestQuestions.Add(ParseCheckTest(questionElement));
                                break;
                            case TestTypes.RadioTest:
                                testData.RadioTestQuestions.Add(ParseRadioTest(questionElement));
                                break;
                            case TestTypes.InputTest:
                                testData.InputTestQuestions.Add(ParseInputTest(questionElement));
                                break;
                            case TestTypes.MatchTest:
                                testData.MatchTestQuestions.Add(ParseMatchTest(questionElement));
                                break;
                            case TestTypes.FillTest:
                                testData.FillTestQuestions.Add(ParseFillTest(questionElement));
                                break;
                            case TestTypes.EsseTest:
                            //break;
                            default:
                                continue;
                        }
                    }
                }
            }

            return testData;
        }

        private static CheckTest ParseCheckTest(XElement xElement)
        {
            var checkTest = new CheckTest();

            checkTest.QuestionText = xElement.Element("questionText").Value; ;
            var possibleAnswers = xElement.Elements("statement").ToList();
            for (int i = 0; i < possibleAnswers.Count(); i++)
            {
                var incorrect = String.Equals(possibleAnswers[i].Attribute("correct").Value, "0");
                checkTest.Statements.Add(new Pair<string, bool>(possibleAnswers[i].Value, !incorrect));
            }
            return checkTest;
        }
        private static RadioTest ParseRadioTest(XElement xElement)
        {
            var radioTest = new RadioTest();
            radioTest.QuestionText = xElement.Element("questionText").Value;
            int answer, id;
            if (Int32.TryParse(xElement.Element("answer").Value, out answer))
            {
                radioTest.Answer = answer;
                var possibleAnswers = xElement.Elements("statement").ToList();

                for (int i = 0; i < possibleAnswers.Count(); i++)
                {
                    if (Int32.TryParse(possibleAnswers[i].Attribute("id").Value, out id))
                    {
                        radioTest.Statements.Add(id, possibleAnswers[i].Value);
                    }
                }
            }

            return radioTest;
        }
        private static InputTest ParseInputTest(XElement xElement)
        {
            var inputTest = new InputTest();
            inputTest.QuestionText = xElement.Element("questionText").Value;
            inputTest.Answer = xElement.Element("answer").Value;

            return inputTest;
        }
        private static MatchTest ParseMatchTest(XElement xElement)
        {
            var matchTest = new MatchTest();
            var leftStatements = xElement.Elements("leftStatement").ToList();
            var rightStatements = xElement.Elements("rightStatement").ToList();
            int id;

            for (int i = 0; i < leftStatements.Count; i++)
            {
                if (Int32.TryParse(leftStatements[i].Attribute("correspondingRight").Value, out id))
                {
                    matchTest.LeftStatements.Add(new Pair<string, int>(leftStatements[i].Value, id));
                }
            }
            for (int i = 0; i < rightStatements.Count; i++)
            {
                if (Int32.TryParse(rightStatements[i].Attribute("id").Value, out id) && !matchTest.RightStatements.ContainsKey(id))
                {
                    matchTest.RightStatements.Add(id, rightStatements[i].Value);
                }
            }

            return matchTest;
        }
        private static FillTest ParseFillTest(XElement xElement)
        {
            var fillTest = new FillTest();
            fillTest.Text = xElement.Element("text").Value;

            var statements = xElement.Elements("statement").ToList();
            foreach (var statement in statements)
            {
                int id;
                if (Int32.TryParse(statement.Attribute("id").Value, out id))
                {
                    fillTest.Statements.Add(id, statement.Value);
                }
            }
            return fillTest;
        }
    }
}